function e(e) {
    var r, a = 348;
    for (r = 32768; r > 8; r >>= 1) a += c[e - 1900] & r ? 1 : 0;
    return a + t(e);
}

function t(e) {
    return r(e) ? 65536 & c[e - 1900] ? 30 : 29 : 0;
}

function r(e) {
    return 15 & c[e - 1900];
}

function a(e, t) {
    return c[e - 1900] & 65536 >> t ? 30 : 29;
}

function n(n) {
    var s, i = new Date(n.getFullYear(), n.getMonth(), n.getDate()), h = 0, o = 0, u = new Date(1900, 0, 31), l = Math.round((i - u) / 864e5);
    for (this.dayCyl = l + 40, this.monCyl = 14, s = 1900; s < 2050 && l > 0; s++) l -= o = e(s), 
    this.monCyl += 12;
    for (l < 0 && (l += o, s--, this.monCyl -= 12), this.year = s, this.yearCyl = s - 1864, 
    h = r(s), this.isLeap = !1, s = 1; s < 13 && l > 0; s++) h > 0 && s == h + 1 && 0 == this.isLeap ? (--s, 
    this.isLeap = !0, o = t(this.year)) : o = a(this.year, s), 1 == this.isLeap && s == h + 1 && (this.isLeap = !1), 
    l -= o, 0 == this.isLeap && this.monCyl++;
    0 == l && h > 0 && s == h + 1 && (this.isLeap ? this.isLeap = !1 : (this.isLeap = !0, 
    --s, --this.monCyl)), l < 0 && (l += o, --s, --this.monCyl), this.month = s, this.day = l + 1;
}

function s(n, s) {
    for (var h = n.getFullYear(), o = n.getMonth() + 1, u = n.getDate(), l = 0, y = i(h), f = 1900; f < h; f++) l += e(f);
    for (f = 1; f < o; f++) f == r(h) && (l += t(h)), l += a(h, f);
    y && s && (l += a(h, f)), l += parseInt(u) - 1;
    var c = new Date(1900, 0, 31), g = new Date(c.valueOf() + 864e5 * l);
    this.year = g.getFullYear(), this.month = g.getMonth(), this.day = g.getDate(), 
    this.isLeap = y;
}

function i(e) {
    return e % 4 == 0 && (e % 100 != 0 || e % 400 == 0);
}

function h(e) {
    return m[(e - 1900) % 12];
}

function o(e) {
    return g[e % 10] + p[e % 12];
}

function u(e) {
    var t;
    switch (e) {
      case 10:
        t = "初十";
        break;

      case 20:
        t = "二十";
        break;

      case 30:
        t = "三十";
        break;

      default:
        t = M[Math.floor(e / 10)], t += w[e % 10];
    }
    return t;
}

function l(e, t) {
    return R[t] + Math.floor(b.charAt(24 * (Math.floor(C.charCodeAt(e - 1900)) - 48) + t));
}

function y(e, t, r, a, n, s, i, o, l, y, f) {
    this.sYear = e, this.sMonth = t, this.sDay = r, this.week = a, this.lYear = n, this.lMonth = s, 
    this.lDay = i, this.isLeap = o, this.cYear = l, this.cMonth = y, this.cDay = f, 
    this.lunarDay = u(i), this.lunarMonth = D[s - 1], this.lunarYear = h(n), this.lunarFestival = "", 
    this.solarFestival = "", this.solarTerms = "";
}

function f(e, t, r, n, s, i, h, u) {
    var f, c, g = {};
    f = o(t < 2 ? e - 1900 + 36 - 1 : e - 1900 + 36);
    var p = l(e, 2), m = l(e, 2 * t);
    c = o(12 * (e - 1900) + t + 12), 1 == t && r >= p && (f = o(e - 1900 + 36)), r >= m && (c = o(12 * (e - 1900) + t + 13)), 
    g = new y(e, t + 1, r, n, s, i, h, u, f, c, o(Date.UTC(e, t, 1, 0, 0, 0, 0) / 864e5 + 25567 + 10 + r - 1));
    var w = l(e, 2 * t) - 1, M = l(e, 2 * t + 1) - 1;
    w == r - 1 && (g.solarTerms = L[2 * t]), M == r - 1 && (g.solarTerms = L[2 * t + 1]);
    for (var D, R = 0; D = v[R]; R++) D.match(/^(\d{2})(\d{2})([\s\*])(.+)$/) && Number(RegExp.$1) == t + 1 && Number(RegExp.$2) == r && (g.solarFestival += RegExp.$4 + " ");
    for (R = 0, D; D = d[R]; R++) if (D.match(/^(\d{2})(\d)(\d)([\s\*])(.+)$/) && Number(RegExp.$1) == t + 1 && (w = Number(RegExp.$2), 
    M = Number(RegExp.$3), w < 5 && (0 == M ? 7 : 0) + 7 * (w - 1) + M == r)) {
        g.solarFestival += RegExp.$5 + " ";
        break;
    }
    for (R = 0, D; D = A[R]; R++) if (D.match(/^(\d{2})(.{2})([\s\*])(.+)$/)) {
        w = Number(RegExp.$1), M = Number(RegExp.$2);
        var C = a(s, i);
        if (w == i && M == h || "00" == M && 12 == i && C == h) {
            g.lunarFestival += RegExp.$4 + " ";
            break;
        }
    }
    return g;
}

var c = new Array(19416, 19168, 42352, 21717, 53856, 55632, 91476, 22176, 39632, 21970, 19168, 42422, 42192, 53840, 119381, 46400, 54944, 44450, 38320, 84343, 18800, 42160, 46261, 27216, 27968, 109396, 11104, 38256, 21234, 18800, 25958, 54432, 59984, 28309, 23248, 11104, 100067, 37600, 116951, 51536, 54432, 120998, 46416, 22176, 107956, 9680, 37584, 53938, 43344, 46423, 27808, 46416, 86869, 19872, 42448, 83315, 21200, 43432, 59728, 27296, 44710, 43856, 19296, 43748, 42352, 21088, 62051, 55632, 23383, 22176, 38608, 19925, 19152, 42192, 54484, 53840, 54616, 46400, 46496, 103846, 38320, 18864, 43380, 42160, 45690, 27216, 27968, 44870, 43872, 38256, 19189, 18800, 25776, 29859, 59984, 27480, 21952, 43872, 38613, 37600, 51552, 55636, 54432, 55888, 30034, 22176, 43959, 9680, 37584, 51893, 43344, 46240, 47780, 44368, 21977, 19360, 42416, 86390, 21168, 43312, 31060, 27296, 44368, 23378, 19296, 42726, 42208, 53856, 60005, 54576, 23200, 30371, 38608, 19415, 19152, 42192, 118966, 53840, 54560, 56645, 46496, 22224, 21938, 18864, 42359, 42160, 43600, 111189, 27936, 44448), g = new Array("甲", "乙", "丙", "丁", "戊", "己", "庚", "辛", "壬", "癸"), p = new Array("子", "丑", "寅", "卯", "辰", "巳", "午", "未", "申", "酉", "戌", "亥"), m = new Array("鼠", "牛", "虎", "兔", "龙", "蛇", "马", "羊", "猴", "鸡", "狗", "猪"), w = (new Array(0, 21208, 42467, 63836, 85337, 107014, 128867, 150921, 173149, 195551, 218072, 240693, 263343, 285989, 308563, 331033, 353350, 375494, 397447, 419210, 440795, 462224, 483532, 504758), 
new Array("日", "一", "二", "三", "四", "五", "六", "七", "八", "九", "十")), M = new Array("初", "十", "廿", "卅", "□"), D = new Array("正", "二", "三", "四", "五", "六", "七", "八", "九", "十", "十一", "腊"), v = new Array("0101*元旦", "0214 情人节", "0308 妇女节", "0312 植树节", "0401 愚人节", "0422 地球日", "0501 劳动节", "0504 青年节", "0531 无烟日", "0601 儿童节", "0606 爱眼日", "0701 建党日", "0707 抗战纪念日", "0801 建军节", "0910 教师节", "0918 九·一八事变纪念日", "1001*国庆节", "1031 万圣节", "1111 光棍节", "1201 艾滋病日", "1213 南京大屠杀纪念日", "1224 平安夜", "1225 圣诞节"), d = new Array("0520 母亲节", "0630 父亲节", "1144 感恩节"), A = new Array("0101*春节", "0115 元宵节", "0202 龙抬头", "0505 端午节", "0707 七夕", "0715 中元节", "0815 中秋节", "0909 重阳节", "1208 腊八节", "1223 小年", "0100*除夕"), L = new Array("小寒", "大寒", "立春", "雨水", "惊蛰", "春分", "清明", "谷雨", "立夏", "小满", "芒种", "夏至", "小暑", "大暑", "立秋", "处暑", "白露", "秋分", "寒露", "霜降", "立冬", "小雪", "大雪", "冬至"), R = new Array(4, 19, 3, 18, 4, 19, 4, 19, 4, 20, 4, 20, 6, 22, 6, 22, 6, 22, 7, 22, 6, 21, 6, 21), C = "0123415341536789:;<9:=<>:=1>?012@015@015@015AB78CDE8CD=1FD01GH01GH01IH01IJ0KLMN;LMBEOPDQRST0RUH0RVH0RWH0RWM0XYMNZ[MB\\]PT^_ST`_WH`_WH`_WM`_WM`aYMbc[Mde]Sfe]gfh_gih_Wih_WjhaWjka[jkl[jmn]ope]qph_qrh_sth_W", b = "211122112122112121222211221122122222212222222221222122222232222222222222222233223232223232222222322222112122112121222211222122222222222222222222322222112122112121222111211122122222212221222221221122122222222222222222222223222232222232222222222222112122112121122111211122122122212221222221221122122222222222222221211122112122212221222211222122222232222232222222222222112122112121111111222222112121112121111111222222111121112121111111211122112122112121122111222212111121111121111111111122112122112121122111211122112122212221222221222211111121111121111111222111111121111111111111111122112121112121111111222111111111111111111111111122111121112121111111221122122222212221222221222111011111111111111111111122111121111121111111211122112122112121122211221111011111101111111111111112111121111121111111211122112122112221222211221111011111101111111110111111111121111111111111111122112121112121122111111011111121111111111111111011111111112111111111111011111111111111111111221111011111101110111110111011011111111111111111221111011011101110111110111011011111101111111111211111001011101110111110110011011111101111111111211111001011001010111110110011011111101111111110211111001011001010111100110011011011101110111110211111001011001010011100110011001011101110111110211111001010001010011000100011001011001010111110111111001010001010011000111111111111111111111111100011001011001010111100111111001010001010000000111111000010000010000000100011001011001010011100110011001011001110111110100011001010001010011000110011001011001010111110111100000010000000000000000011001010001010011000111100000000000000000000000011001010001010000000111000000000000000000000000011001010000010000000";

module.exports = {
    CalendarConverter: function() {
        this.solar2lunar = function(e) {
            var t = e.getFullYear(), r = e.getMonth(), a = e.getDate(), s = w[e.getDay()], i = new n(e);
            return f(t, r, a, s, i.year, i.month, i.day, i.isLeap);
        }, this.lunar2solar = function(e, t) {
            var r = e.getFullYear(), a = e.getMonth() + 1, n = e.getDate(), i = new s(e, t), h = i.year, o = i.month, u = i.day;
            return f(h, o, u, w[new Date(h, o, u).getDay()], r, a, n, i.isLeap);
        };
    }
};